package com.topisv.tms.service.qimen;

import java.io.StringReader;
import java.io.StringWriter;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.xml.bind.JAXB;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.topisv.tms.entity.Area;
import com.topisv.tms.entity.EdiGoodsSku;
import com.topisv.tms.entity.EdiOrder;
import com.topisv.tms.entity.qimen.DeliveryOrderTask;
import com.topisv.tms.entity.qimen.OrderProcessConfig;
import com.topisv.tms.repository.EdiGoodsSkuDao;
import com.topisv.tms.repository.qimen.DeliveryOrderTaskDao;
import com.topisv.tms.repository.qimen.OrderProcessConfigDao;
import com.topisv.tms.rest.qimen.qmentity.ReceiverInfo;
import com.topisv.tms.rest.qimen.qmentity.request.deliveryorder.DeliveryOrderItem;
import com.topisv.tms.rest.qimen.qmentity.request.deliveryorder.DeliveryOrderRequest;
import com.topisv.tms.rest.qimen.util.delivery.TransferHelper;
import com.topisv.tms.service.AreaService;
import com.topisv.tms.service.EdiOrderService;
import com.topisv.tms.service.WarehouseAreaService;
import com.topisv.tms.utils.InitProperties;
import com.topisv.tms.utils.enums.TaskStatus;

/**
 * 发货单任务逻辑类 Date Author Version Description
 * ---------------------------------------------------------- 2015-5-8 CC 1.0
 * Create 
 */
@Component
public class DeliveryOrderTaskService {
	private Logger log = LoggerFactory.getLogger(DeliveryOrderTaskService.class);
	@Autowired
	private DeliveryOrderTaskDao deliveryOrderTaskDao;
	@Autowired
	private EdiOrderService ediOrderService;
	@Autowired
	private EdiGoodsSkuDao ediGoodsSkuDao;
	@Autowired
	private OrderProcessConfigDao orderProcessConfigDao;

	@Autowired
	private AreaService areaService;
	@Autowired
	private WarehouseAreaService warehouseAreaService;
	@PersistenceContext
	private EntityManager em;
	private String node;
	private int num;

	public static boolean useDistributeWarehouse = true; // 分仓启用开关

	/**
	 * 根据计算机名查询所有的配置
	 * 
	 *
	 * @return [参数说明]
	 * @author <a href=mailto:zhangweize@nryuncang.com>zhangweize</a>
	 * @version 1.0.0
	 */
	public List<OrderProcessConfig> findOrderProcessConfigByIp() {

		return orderProcessConfigDao.findOrderProcessConfigByIp(getNode());
	}

	/**
	 * 根据仓库编码查询配置
	 * 
	 *
	 * @param warehouseCode
	 * @return [参数说明]
	 * @author <a href=mailto:zhangweize@nryuncang.com>zhangweize</a>
	 * @version 1.0.0
	 */
	public OrderProcessConfig findOrderProcessConfigByWarehouse(String warehouseCode) {

		return orderProcessConfigDao.findOrderProcessConfigByWarehouse(warehouseCode);
	}

	/**
	 * 手动锁定数据
	 * 
	 * [参数说明]
	 * 
	 * @author <a href=mailto:zhangweize@nryuncang.com>zhangweize</a>
	 * @version 1.0.0
	 */
	@SuppressWarnings("unchecked")
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public void manualLockData(String warehouseCode, String customerCode, int limitNum, String fromDate, String toDate) {
		StringBuilder sql = new StringBuilder();
		sql.append(
				"select t.id from tt_delivery_order_task t  where deal_ip = ?2  and deal_status = ?3 and warehouse_code = ?4 and cr_time >= ?5 and cr_time <= ?6");
		if (StringUtils.isNotBlank(customerCode)) {
			sql.append(" and customer_code = ?7");
		}
		sql.append("  order by id  limit ?1");
		Query querySql = em.createNativeQuery(sql.toString());
		querySql.setParameter(1, limitNum);
		querySql.setParameter(2, "-");
		querySql.setParameter(3, "0");
		querySql.setParameter(4, warehouseCode);
		querySql.setParameter(5, fromDate);
		querySql.setParameter(6, toDate);
		if (StringUtils.isNotBlank(customerCode)) {
			querySql.setParameter(7, customerCode);
		}
		List<Long> idRs = querySql.getResultList();
		if (!idRs.isEmpty()) {
			Query updateSql = em.createNativeQuery(
					"update tt_delivery_order_task t set t.deal_ip = ?1,t.deal_time = now(),deal_status='1' where t.id in ?2 and deal_status='0' ");
			updateSql.setParameter(1, getNode());
			updateSql.setParameter(2, idRs);
			updateSql.executeUpdate();
		}
	}

	/**
	 * 手动查询数据
	 * 
	 *
	 * @param id
	 * @return [参数说明]
	 * @author <a href=mailto:zhangweize@nryuncang.com>zhangweize</a>
	 * @version 1.0.0
	 */
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public List<DeliveryOrderTask> manualFindData(String warehouseCode, String customerCode) {

		List<DeliveryOrderTask> tasks = deliveryOrderTaskDao.findTask(getNode(), warehouseCode, customerCode, getDateBefore(new Date(), 2), new Date());
		if (!tasks.isEmpty()) {
			deliveryOrderTaskDao.update(getNode(), findIds(tasks));
		}
		return tasks;
	}

	/**
	 * 锁定数据
	 */
	@SuppressWarnings("unchecked")
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public List<Long> lockData(Map<String, Object> param) {
		Query querySql = em.createNativeQuery(
				"select t.id from tt_delivery_order_task t  where deal_ip = ?2  and deal_status = ?3 and warehouse_code = ?4 and cr_time >= ?5 and cr_time <= ?6  order by id limit ?1");
		querySql.setParameter(1, getNum());
		querySql.setParameter(2, "-");
		querySql.setParameter(3, "0");
		querySql.setParameter(4, param.get("warehouseCode"));
		querySql.setParameter(5, param.get("fromDate"));
		querySql.setParameter(6, param.get("toDate"));
		List<Long> idRs = querySql.getResultList();
		if (!idRs.isEmpty()) {
			Query updateSql = em.createNativeQuery(
					"update tt_delivery_order_task t set t.deal_ip = ?1,t.deal_time = now(),deal_status='1' where t.id in ?2 and deal_status='0' ");
			updateSql.setParameter(1, getNode());
			updateSql.setParameter(2, idRs);
			updateSql.executeUpdate();
		}
		return idRs;
	}

	/**
	 * 加载数据
	 * 
	 * @return List<DeliveryOrderTask>
	 */
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public List<DeliveryOrderTask> findData(String warehouseCode) {

		List<DeliveryOrderTask> tasks = deliveryOrderTaskDao.findTask(getNode(), warehouseCode, getDateBefore(new Date(), 2), new Date());
		if (!tasks.isEmpty()) {
			deliveryOrderTaskDao.update(getNode(), findIds(tasks));
		}
		return tasks;
	}

	private List<Long> findIds(List<DeliveryOrderTask> tasks) {
		List<Long> rs = new ArrayList<Long>();
		for (DeliveryOrderTask task : tasks) {
			rs.add(task.getId());
		}
		return rs;
	}

	/**
	 * 
	 * 得到几天前的时间 
	 *
	 * @param d
	 * @param day
	 * @return [参数说明]
	 * @author <a href=mailto:zhangweize@nryuncang.com>zhangweize</a>
	 * @version 1.0.0
	 */
	public static Date getDateBefore(Date d, int day) {  
        Calendar now = Calendar.getInstance();  
        now.setTime(d);  
        now.set(Calendar.DATE, now.get(Calendar.DATE) - day);  
        now.set(Calendar.HOUR_OF_DAY,0);
        now.set(Calendar.MINUTE,0);
        now.set(Calendar.SECOND,0);
        return now.getTime();  
    }
	
	/**
	 * 保存数据
	 * 
	 * @param task
	 */
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public void saveData(DeliveryOrderTask task) {
//		deliveryOrderTaskDao.save(task);
	    //modify 20161027
	    int cnt = deliveryOrderTaskDao.update(task.getId(), task.getDealIp(), task.getDealStatus(), new Date(), task.getDealCount());
	    if (cnt == 0) {
	        log.info("DeliveryOrderTask 已被取消，不再更新状态等信息。task.id:{}", task.getId());
	    }
	}

	/**
	 * 处理数据
	 * 
	 * @param task
	 */
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public void dealData(DeliveryOrderTask task) throws Exception {
		if (!getNode().equals(task.getDealIp())) {
			return;
		}

		// modify 20161025 取消单拦截报文，直接更新报文状态，防止覆盖，此处不使用该方式进行数据保存，修改见方法最后
		// task.setDealStatus(TaskStatus.SUCCESS.getStatus());

		Map<String, EdiGoodsSku> skuMap = new HashMap<String, EdiGoodsSku>();
		DeliveryOrderRequest orderRequest = JAXB.unmarshal(new StringReader(task.getContent()),
				DeliveryOrderRequest.class);

		// add by yuansheng 分仓处理
		long t1 = System.currentTimeMillis();
		distributeOrder(orderRequest, task);
		long t2 = System.currentTimeMillis();
		log.info("接单job处理，分仓耗时：task.id: {} ,订单转换处理时间：{} ms ,商家单号: {}", task.getId(), t2 - t1,
				orderRequest.getDeliveryOrder().getDeliveryOrderCode());
				// add by yuansheng 分仓处理

		// 来源网站代码字段为“null”时，mobile字段为“null”时的处理
		String sourcePlatformCode = orderRequest.getDeliveryOrder().getSourcePlatformCode();
		if (StringUtils.isNotBlank(sourcePlatformCode) && "null".equals(sourcePlatformCode.toLowerCase())) {
			orderRequest.getDeliveryOrder().setSourcePlatformCode(null);
		}
		String mobile = orderRequest.getDeliveryOrder().getReceiverInfo().getMobile();
		if (StringUtils.isNotBlank(mobile) && "null".equals(mobile.toLowerCase())) {
			orderRequest.getDeliveryOrder().getReceiverInfo().setMobile(null);
		}

		fillCache(orderRequest, skuMap);
		ReceiverInfo receiverInfo = orderRequest.getDeliveryOrder().getReceiverInfo();
		Area area = areaService.getTopAreaBy(receiverInfo.getProvince(), receiverInfo.getCity());
		log.info("------------------------------------CheckRepeat start--------------------------------------");

		EdiOrder ediOrder = TransferHelper.toEdiOrder(orderRequest, task, skuMap, area);
		log.info("dealData_ediOrder_CheckRepeat" + ediOrder.getCheckRepeat());
		log.info("ediOrder" + ediOrder);
		log.info("------------------------------------CheckRepeat end--------------------------------------");
		ediOrder.setDispatchFlag("1");
		// add by yanlei 防止重复推单
		// List<EdiOrder> ediOrder1 =
		// ediOrderService.findByCustomerCodeAndCustomerOrdenoAndOrderStatus(ediOrder.getCustomerCode(),
		// ediOrder.getCustomerOrdeno());
		// if (!ediOrder1.isEmpty()) {
		// ediOrder.setStatus("repeat");
		// ediOrder.setMessage("订单重复流入");
		// log.info("奇门订单重复流入："+ediOrder.getCustomerCode() + "+++" +
		// ediOrder.getCustomerOrdeno());
		// }
		// else
		// {
		// 校验库存
		if (ediOrderService.ifMerge(ediOrder.getCustomerCode())) {
			Map<String, Integer> map = ediOrderService.setCusStock(ediOrder);
			if (map != null) {
				ediOrderService.mergeCusStock(ediOrder, ediOrder.getWarehouseCode(), true);
			} else {
				// 库存不足时,发出缺货通知
				// orderOutofstockService.send(ediOrder,
				// ediOrder.getCustomerCode());
				ediOrder.setDispatchFlag("0");
			}
		}
		ediOrderService.saveEdiOrder(ediOrder, false);
		// }

		// deliveryOrderTaskDao.save(task);
		// add 20161025
		int cnt = deliveryOrderTaskDao.update(task.getId(), TaskStatus.SUCCESS.getStatus(), new Date());
		if (cnt == 0) {
			throw new RuntimeException("接单job处理订单:DeliveryOrderTask不存在或者已被取消。id:" + task.getId() + "。");
		}
	}

	/**
	 * 分仓处理
	 *
	 * @param
	 * @return
	 * @throws @author
	 *             yuansheng
	 * @version 1.0.0
	 */
	private void distributeOrder(DeliveryOrderRequest deliveryOrderRequest, DeliveryOrderTask task) {
		try {
			if (useDistributeWarehouse) {
				log.info("=================系统启用分仓:" + deliveryOrderRequest.getDeliveryOrder().getDeliveryOrderCode());
				String warehouseCode = warehouseAreaService.distributeOrder(deliveryOrderRequest);
				if (StringUtils.isNotBlank(warehouseCode)) {
					// 设置分仓
					deliveryOrderRequest.getDeliveryOrder().setWarehouseCode(warehouseCode);
					StringWriter swt = new StringWriter();
					JAXB.marshal(deliveryOrderRequest, swt);
					task.setContent(swt.toString());
				}
			} else {
				log.info("=================系统未启用分仓:" + deliveryOrderRequest.getDeliveryOrder().getDeliveryOrderCode());
			}
		} catch (Exception e) {
			log.info("分仓异常：", e);
		}
	}

	private void fillCache(DeliveryOrderRequest orderRequest, Map<String, EdiGoodsSku> skuMap) {
		List<DeliveryOrderItem> items = orderRequest.getDeliveryOrderItems();
		for (DeliveryOrderItem deliveryOrderItem : items) {
			EdiGoodsSku ediGoodsSku = skuMap.get(deliveryOrderItem.getItemCode());
			if (ediGoodsSku == null) {
				// add by yanlei 2016-5-7 临时修改 处理卡利雅异常订单
				EdiGoodsSku goodsSku = null;
				if ("KLY".equals(deliveryOrderItem.getOwnerCode())) {
					goodsSku = ediGoodsSkuDao.findByCustomerCodeAndSku("KLY", deliveryOrderItem.getItemCode());
				} else {
					goodsSku = ediGoodsSkuDao.findOne(Long.valueOf(deliveryOrderItem.getItemId()));
				}
				// EdiGoodsSku goodsSku =
				// ediGoodsSkuDao.findOne(Long.valueOf(deliveryOrderItem.getItemId()));
				skuMap.put(deliveryOrderItem.getItemCode(), goodsSku);
			}
		}
	}

	public String getNode() {
		if (node == null) {
			String name = ManagementFactory.getRuntimeMXBean().getName();
			node = name.substring(name.indexOf("@") + 1);
		}
		return node;
	}

	public int getNum() {
		if (num == 0) {
			String numParam = InitProperties.get("qm.loaddata.num");
			num = StringUtils.isBlank(numParam) ? 1 : Integer.valueOf(numParam);
		}
		return num;
	}

}
